import * as vscode from 'vscode';
import * as path from 'path';
import { DeepseekAPI } from './deepseekAPI';

export class CodebaseAnalyzer {
    private deepseekAPI: DeepseekAPI;

    constructor(deepseekAPI: DeepseekAPI) {
        this.deepseekAPI = deepseekAPI;
    }

    // 读取工作区所有文件
    public async getAllWorkspaceFiles(
        excludePatterns: string[] = ['node_modules', 'dist', '.git']
    ): Promise<{ path: string; content: string }[]> {
        const files: { path: string; content: string }[] = [];
        
        // 获取所有工作区文件夹
        const workspaceFolders = vscode.workspace.workspaceFolders;
        if (!workspaceFolders) {
            return files;
        }

        for (const folder of workspaceFolders) {
            // 使用 VSCode 的文件查找 API
            const pattern = new vscode.RelativePattern(folder, '**/*');
            const excludePattern = `{${excludePatterns.join(',')}}/**`;
            
            const uris = await vscode.workspace.findFiles(pattern, excludePattern);
            
            // 读取每个文件的内容
            for (const uri of uris) {
                try {
                    const document = await vscode.workspace.openTextDocument(uri);
                    const relativePath = path.relative(folder.uri.fsPath, uri.fsPath);
                    files.push({
                        path: relativePath,
                        content: document.getText()
                    });
                } catch (error) {
                    console.warn(`Failed to read file: ${uri.fsPath}`, error);
                }
            }
        }

        return files;
    }

    // 分析整个代码库
    public async analyzeCodebase(options: {
        maxFiles?: number;
        includePatterns?: string[];
        excludePatterns?: string[];
    } = {}): Promise<any> {
        const {
            maxFiles = 50,
            excludePatterns = ['node_modules', 'dist', '.git', '*.map', '*.min.*']
        } = options;

        try {
            // 获取所有文件
            const files = await this.getAllWorkspaceFiles(excludePatterns);
            
            // 限制文件数量
            const selectedFiles = files.slice(0, maxFiles);
            
            // 准备代码库概述
            const codebaseOverview = selectedFiles.map(file => ({
                path: file.path,
                size: file.content.length,
                type: path.extname(file.path)
            }));

            // 发送到 API 进行分析
            const analysis = await this.deepseekAPI.analyzeCodebase({
                files: selectedFiles,
                overview: codebaseOverview
            });

            return analysis;
        } catch (error) {
            console.error('Failed to analyze codebase:', error);
            throw error;
        }
    }

    // 搜索代码库
    public async searchCodebase(query: string): Promise<any> {
        try {
            const files = await this.getAllWorkspaceFiles();
            const results = [];

            for (const file of files) {
                if (file.content.includes(query)) {
                    const lines = file.content.split('\n');
                    const matches = lines
                        .map((line, index) => ({ line, index: index + 1 }))
                        .filter(({ line }) => line.includes(query));

                    results.push({
                        file: file.path,
                        matches: matches.map(({ line, index }) => ({
                            line: index,
                            content: line.trim(),
                            preview: this.getLineContext(lines, index)
                        }))
                    });
                }
            }

            return results;
        } catch (error) {
            console.error('Failed to search codebase:', error);
            throw error;
        }
    }

    private getLineContext(lines: string[], lineNumber: number, context: number = 2): string[] {
        const start = Math.max(0, lineNumber - context - 1);
        const end = Math.min(lines.length, lineNumber + context);
        return lines.slice(start, end);
    }

    public async analyze(code: string) {
        try {
            const response = await this.deepseekAPI.chat(
                [
                    {
                        role: 'system',
                        content: '你是一个代码分析助手，请分析以下代码并提供改进建议。'
                    },
                    {
                        role: 'user',
                        content: code
                    }
                ],
                'deepseek-reasoner'  // 使用 R1 模型进行分析
            );

            // 获取分析结果和思维链
            const analysis = response.choices[0].message.content;
            const reasoning = response.choices[0].message.reasoning_content;

            // 创建分析结果文档
            const document = await vscode.workspace.openTextDocument({
                content: `# 代码分析结果\n\n## 思维过程\n${reasoning || '无'}\n\n## 分析结果\n${analysis}`,
                language: 'markdown'
            });

            await vscode.window.showTextDocument(document);

            return {
                analysis,
                reasoning,
                suggestions: response.choices[0].message.content.split('\n')
                    .filter(line => line.trim().startsWith('-'))
                    .map(line => line.trim().substring(2))
            };
        } catch (error) {
            console.error('Error analyzing code:', error);
            throw error;
        }
    }

    public async suggestChanges(text: string): Promise<any[]> {
        try {
            const response = await this.deepseekAPI.suggestCodeChanges(text);
            return response.suggestions || [];
        } catch (error) {
            console.error('Suggest changes error:', error);
            return [];
        }
    }

    public async applyChanges(editor: vscode.TextEditor, suggestions: any[]): Promise<void> {
        const edit = new vscode.WorkspaceEdit();
        for (const suggestion of suggestions) {
            if (suggestion.range && suggestion.newText) {
                edit.replace(
                    editor.document.uri,
                    new vscode.Range(
                        editor.document.positionAt(suggestion.range.start),
                        editor.document.positionAt(suggestion.range.end)
                    ),
                    suggestion.newText
                );
            }
        }
        await vscode.workspace.applyEdit(edit);
    }
} 